using System;

namespace IBNet
{
   /// <summary>
   /// Contract details returned from Interactive Brokers. This class is immutable.
   /// </summary>
   public class ContractDetails
   {
      #region Fields

      private readonly Contract contract;
      private readonly decimal minTick;
      private readonly string orderTypes;
      private readonly int priceMagnifier;
      private readonly string marketName;
      private readonly string tradingClass;
      private readonly string validExchanges;

      // Bond values
      private readonly string cusip;
      private readonly string ratings;
      private readonly string descriptionAppend;
      private readonly string bondType;
      private readonly string couponType;
      private readonly bool callable;
      private readonly bool putable;
      private readonly decimal coupon;
      private readonly bool convertible;
      private readonly string maturity;
      private readonly string issueDate;
      private readonly string nextOptionDate;
      private readonly string nextOptionType;
      private readonly bool nextOptionPartial;
      private readonly string notes;

      #endregion

      #region Constructors

      /// <summary>
      /// Creates a new ContractDetails.
      /// </summary>
      public ContractDetails(Contract contract, decimal minTick, string orderTypes,
         int priceMagnifier, string marketName, string tradingClass, string validExchanges,
         string cusip, string ratings, string descriptionAppend, string bondType,
         string couponType, bool callable, bool putable, decimal coupon, bool convertible,
         string maturity, string issueDate, string nextOptionDate, string nextOptionType,
         bool nextOptionPartial, string notes)
      {
         this.marketName = marketName;
         this.minTick = minTick;
         this.orderTypes = orderTypes;
         this.priceMagnifier = priceMagnifier;
         this.contract = contract;
         this.tradingClass = tradingClass;
         this.validExchanges = validExchanges;
         this.cusip = cusip;
         this.ratings = ratings;
         this.descriptionAppend = descriptionAppend;
         this.bondType = bondType;
         this.couponType = couponType;
         this.callable = callable;
         this.putable = putable;
         this.coupon = coupon;
         this.convertible = convertible;
         this.maturity = maturity;
         this.issueDate = issueDate;
         this.nextOptionDate = nextOptionDate;
         this.nextOptionType = nextOptionType;
         this.nextOptionPartial = nextOptionPartial;
         this.notes = notes;
      }

      public ContractDetails(Contract contract, string marketName, string tradingClass,
         decimal minTick, string orderTypes, string validExchanges)
      {
         this.contract = contract;
         this.marketName = marketName;
         this.tradingClass = tradingClass;
         this.minTick = minTick;
         this.orderTypes = orderTypes;
         this.validExchanges = validExchanges;
      }

      #endregion

      #region Properties

      /// <summary>
      /// Gets the contract summary.
      /// </summary>
      public Contract Contract { get { return contract; } }

      /// <summary>
      /// Gets the minimum tick.
      /// </summary>
      public decimal MinTick { get { return minTick; } }

      /// <summary>
      /// Gets the valid order types for this contract.
      /// </summary>
      public string OrderTypes { get { return orderTypes; } }

      /// <summary>
      /// Gets the price magnifier.
      /// </summary>
      public int PriceMagnifier { get { return priceMagnifier; } }

      /// <summary>
      /// Gets the market name for this contract.
      /// </summary>
      public string MarketName { get { return marketName; } }

      /// <summary>
      /// Gets the trading class.
      /// </summary>
      public string TradingClass { get { return tradingClass; } }

      /// <summary>
      /// Gets the exchanges this contract is traded on.
      /// </summary>
      public string ValidExchanges { get { return validExchanges; } }
      
      /// <summary>
      /// Gets the nine-character bond CUSIP or the 12-character SEDOL.
      /// </summary>
      public string Cusip { get { return cusip; } }

      /// <summary>
      /// Gets the bond ratings. Bond ratings are from Moody's and SP.
      /// </summary>
      public string Ratings { get { return ratings; } }

      /// <summary>
      /// Gets the bond description append.
      /// </summary>
      public string DescriptionAppend { get { return descriptionAppend; } }

      /// <summary>
      /// Gets the bond type, such as "CORP."
      /// </summary>      
      public string BondType { get { return bondType; } }

      /// <summary>
      /// Gets the bond coupon type.
      /// </summary>
      public string CouponType { get { return couponType; } }

      /// <summary>
      /// Gets a value indicating whether the bond is callable.
      /// </summary>
      public bool Callable { get { return callable; } }

      /// <summary>
      /// Gets a value indicating whether the bond is putable.
      /// </summary>
      public bool Putable { get { return putable; } }

      /// <summary>
      /// Gets the bond coupon, such as "FIXED."
      /// </summary>
      public decimal Coupon { get { return coupon; } }

      /// <summary>
      /// Gets a value indicating whether the bond is convertible.
      /// </summary>
      public bool Convertible { get { return convertible; } }

      /// <summary>
      /// Gets the bond maturity.
      /// </summary>
      public string Maturity { get { return maturity; } }

      /// <summary>
      /// Gets the bond issue date.
      /// </summary>
      public string IssueDate { get { return issueDate; } }

      /// <summary>
      /// Gets the bond next option date. Relevant if the bond has embedded options.
      /// </summary>
      public string NextOptionDate { get { return nextOptionDate; } }

      /// <summary>
      /// Gets the bond next option type. Relevant if the bond has embedded options.
      /// </summary>
      public string NextOptionType { get { return nextOptionType; } }

      /// <summary>
      /// Gets the bond next option partial. Relevant if the bond has embedded options.
      /// </summary>
      public bool NextOptionPartial { get { return nextOptionPartial; } }

      /// <summary>
      /// Gets the bond notes.
      /// </summary>
      public string Notes { get { return notes; } }

      #endregion
   }
}